<?php
class BudgetFormulaService
{



/*
* 获取地面材料的算法
*
*/
    public static function getNumFromMainGround($case_info,$material)
    {


    }


    /*
    * 中缀表达式－>后缀表达式
    *
    */
    public static function trans_exp($exp)
    {
        $postexp = "";

        for($i=0;$i<strlen(($exp));$i++)
        {
            $postexp .="0";

        }

       // return $postexp;

        //符号栈


        $op_data = array();
        $op_top = -1;

        //数值堆栈

        $st_data = array();
        $st_top = -1;



        //字符
        $i=0;

        $j=0;


        while($i<strlen($exp))
        {
            $ch = substr($exp,$i,1);
            //左括号
            if($ch == "(")
            {
                $op_top++;
                $op_data[$op_top]=$ch;



            }


            //右括号
            //若遇到右括弧“）”，则连续出栈输出，直到遇到左括弧“（”为止。其中，左括弧出栈但是并不输出
            elseif($ch == ")")
            {

                while($op_data[$op_top]!='(')
            {
                $postexp[$j]=$op_data[$op_top]; $j++;
                $op_top--;
            }
                $op_top--;
            break;




            }

            //为'+'或'-'时，其优先级不大于栈顶任何运算符的优先级，直到')'
            elseif($ch == "+" || $ch == "-")
            {

                while ($op_top!=-1 && $op_data[$op_top]!='(')
            {
                $postexp[$j]=$op_data[$op_top];
                $j++;
                $op_top--;
            }

                $op_top++;
                $op_data[$op_top]=$ch;
            break;

            }


            //为'*'或'/'时，其优先级不大于栈顶为'*'或'/'的优先级，直到')'
            elseif($ch == "*" || $ch == "/")
            {

                while($op_top!=-1 && $op_data[$op_top]!='('
                && ($op_data[$op_top]=='*' || $op_data[$op_top]=='/')){
                $postexp[$j]=$op_data[op.top]; $j++;
                    $op_top--;
            }
                $op_top++;
                $op_data[$op_top]=$ch;
            break;


            }
            else
            {
                while ($ch>='0' && $ch<='9')
                {
                    $postexp[$j]=$ch; $j++;
                   $ch=$exp[$i]; $i++;
            }
                $i--;
                $postexp[$j]='#'; $j++;
            }





            //循环

            $i++;


        }




        while($op_top!=-1){ //此时，exp扫描完毕，栈不空时出栈并存放到postexp中
            $postexp[j]=$op_data[$op_top]; $j++;
        $op_top--;
    }


        return $op_data;





    }

/*
**
* 将输入的字符按照中缀表达式转后缀表达式的规则处理
* @param $str 输入的字符
* @param $stack 栈
* @param $newStrList 新的表达式
*/
   public static function suffix($str, &$stack, &$newStrList){
        //如果是数字则输出
        if(is_numeric($str)){
            $newStrList .= $str . ' ';
        }
        //如果是左括号则入栈
        else if($str == '('){
            $stack[] = $str;
        }
        //如果是右括号则将最近的左括号之前的所有数据出栈
        else if($str == ')'){
            while($arrPop = array_pop($stack)){
                if($arrPop == '('){
                    break;
                }
                $newStrList .= $arrPop . ' ';
            }
        }
        //如果是加减乘除则判断与栈顶符号优先级
        else if(in_array($str, array('+', '-', '*', '/')) && count($stack) > 0){
            $key  = (count($stack) - 1);
            if(in_array($stack[$key], array('+', '-', '*', '/'))){
                //该符号优先级不高于栈顶符号的
                if(BudgetFormulaService::checkPriority($str, $stack[$key]) != 1){
                    for($i=$key; $i>=0; $i--){
                        if($stack[$i] == '('){
                            break;
                        }
                        $newStrList .= $stack[$i] . ' ';
                        unset($stack[$i]);
                        $stack = array_values($stack);
                    }
                }
            }
            //本次的符号入栈
            $stack[] = $str;
        }else{
            $stack[] = $str;
        }
    }

    /**
     * 判断运算符的优先级
     * @param $operatorA
     * @param $operatorB
     * @return A大于B返回1，A等于B返回0，A小于B返回-1
     */
   public static function checkPriority($operatorA, $operatorB){
        switch($operatorA){
            case '+':
            case '-':
                if($operatorB == '+' || $operatorB == '-'){
                    return 0;
                }else if($operatorB == '*' || $operatorB == '/'){
                    return -1;
                }
                break;
            case '*':
            case '/':
                if($operatorB == '+' || $operatorB == '-'){
                    return 1;
                }else if($operatorB == '*' || $operatorB == '/'){
                    return 0;
                }
                break;
            default:
                exit('error');
        }
    }


    /*
    *  获取后缀表达式
    *
    */
    public static function getPostExp ($strList)
    {

        $stack = array();
//待转换的表达式
       // $strList = '9 + ( 3 - 1 ) * 3 + 10 / 2';
        //$strList = '2 * 5 + c';

        //$strList = $formula;
//新的表达式
        $newStrList = '';
        $strList = explode(' ', $strList);
        foreach($strList as $str){
            if($str != ' '){
                BudgetFormulaService::suffix($str, $stack, $newStrList);
            }
        }

        //echo $newStrList;
        //print_r($stack);
//数组反转
        while($s = array_pop($stack)){

            $newStrList .= $s;
        }

        return $newStrList;

        //echo $newStrList;


    }


    /*
    * 通过后缀表达式获取数值
    *
    */
    public static function getValueByPostExp($expson)
    {
       // echo $expson."<br>";
        $stack = array();

        $i=-1;

        $strList = explode(' ', $expson);


        $finalstrList = array();

        for($i=0;$i<count($strList);$i++)
        {
            $str = $strList[$i];

            if(strstr($str,"+") || strstr($str,"-") || strstr($str,"*") || strstr($str,"/") )
            {

                for($t=0;$t<strlen($str);$t++)
                {
                    $substr = substr($str,$t,1);

                    array_push($finalstrList,$substr);
                }

            }
            else
            {
                array_push($finalstrList,$str);
            }


        }


        $i=-1;

        //print_r($finalstrList);

        //return;

        foreach($finalstrList as $str){

           // echo "str ".$str."<br>";

            if($str == "+" || $str == "-" || $str == "*" || $str == "/")
            {

                $add1 = $stack[$i];
                $add2 = $stack[$i-1];

                //echo "add1 ".$add1." add2 ".$add2."<br>";

                //加号
                if($str == "+")
                {
                    $result = (int)$add1+(int)$add2;

                    //echo $result;


                }

                //减号
                if($str == "-")
                {
                    $add1 = $stack[$i];
                    $add2 = $stack[$i-1];

                    //echo "add1 ".$add1." add2 ".$add2."<br>";

                    $result = (int)$add2-(int)$add1;

                }


                //减号
                if($str == "*")
                {
                    $add1 = $stack[$i];
                    $add2 = $stack[$i-1];

                    //echo "add1 ".$add1." add2 ".$add2."<br>";

                    $result = (int)$add2 * (int)$add1;

                }

                //除法
                if($str == "/")
                {
                    $add1 = $stack[$i];
                    $add2 = $stack[$i-1];

                    //echo "add1 ".$add1." add2 ".$add2."<br>";

                    $result = (int)$add2/(int)$add1;

                }


                $stack[$i-1] = $result;

                $stack[$i]=0;

                $i--;


            }
            else
            {
                $i++;

                $stack[$i]=$str;
            }

            //print_r($stack);

        }


       // print_r($stack);

        return $stack[0];


    }



}


?>
